DeepWiki

04.a - Stripe-Checkout-Creation

Relevant source files

This document details the createCheckoutSession server action, which initiates Stripe payment processing for the $10 DeepWiki Analysis product. This action creates a Stripe Checkout session, configures the product details, sets up success and cancellation URLs, and redirects the user to Stripe's hosted payment page.

For information about what happens after successful payment, see Stripe Webhook Handling. For the complete payment-to-installation linking mechanism, see Payment-to-Installation Linking.


The Stripe checkout flow begins when a user clicks either payment button on the landing page. The system uses Next.js 14 Server Actions to handle the checkout session creation server-side, ensuring secure API key handling and proper origin detection for redirect URLs.

Server Action Flow Diagram

Sources: app/actions.ts L1-L33

app/page.tsx L5

app/page.tsx L62-L67


The createCheckoutSession function is defined in app/actions.ts L7-L33

with the "use server" directive, marking it as a Next.js Server Action. This allows the function to execute on the server while being invoked directly from client components via form actions.

AspectImplementation
Function NamecreateCheckoutSession
File Locationapp/actions.ts
Execution ContextServer-side only
Return TypePromise<void> (redirects user)
Dependenciesstripe (from @/lib/stripe), headers (from next/headers), redirect (from next/navigation)

The function performs three primary operations:

  1. Origin Detection: Extracts the request origin from HTTP headers
  2. Stripe Session Creation: Calls the Stripe API to create a checkout session
  3. User Redirect: Redirects the user to the Stripe-hosted checkout page

Sources: app/actions.ts L1-L6

app/actions.ts L7-L33


The action uses Next.js headers() API to determine the deployment origin, which is essential for constructing absolute redirect URLs required by Stripe.

Origin Detection Logic

The code at app/actions.ts L8-L9

implements this pattern:

  • await headers(): Retrieves the request headers object
  • .get("origin"): Extracts the Origin HTTP header value
  • || "http://localhost:3000": Provides a development fallback

This origin variable is then used to construct two critical URLs:

URL TypePatternPurpose
Success URL${origin}/success?session_id={CHECKOUT_SESSION_ID}Redirect destination after successful payment
Cancel URL${origin}/?canceled=trueRedirect destination if user cancels payment

The {CHECKOUT_SESSION_ID} placeholder is automatically replaced by Stripe with the actual session ID at redirect time.

Sources: app/actions.ts L8-L9

app/actions.ts L26-L27


The core of the action is the stripe.checkout.sessions.create() call at app/actions.ts L11-L28

which configures the payment session with specific product details and behavior.

Checkout Session Configuration Structure

Sources: app/actions.ts L11-L28

The product is configured inline using Stripe's price_data API, which allows ad-hoc product creation without pre-defining price objects in the Stripe Dashboard.

FieldValueNotes
currency"usd"United States Dollar
product_data.name"DeepWiki Analysis"Displayed on checkout page
product_data.description"Full architectural documentation for your GitHub repository."Additional product context
unit_amount1000Price in cents ($10.00)
quantity1Always 1 (single-repo analysis)
mode"payment"One-time payment (not subscription)

The unit_amount: 1000 at app/actions.ts L20

represents $10.00 because Stripe's API expects amounts in the smallest currency unit (cents for USD).

Sources: app/actions.ts L14-L21


The success and cancel URLs follow specific patterns designed to integrate with the application's user journey.

URL Pattern Mapping

The success URL at app/actions.ts L26

uses the placeholder {CHECKOUT_SESSION_ID}, which Stripe automatically replaces with the actual session ID when redirecting. This pattern:

  • Ensures type safety (no manual string interpolation of session IDs)
  • Allows the success page to retrieve session details from Stripe
  • Serves as the correlation key for linking payment to GitHub installation (see Payment-to-Installation Linking)

The URL resolves to: https://godeep.wiki/success?session_id=cs_test_... (in production)

The cancel URL at app/actions.ts L27

includes a canceled=true query parameter. While the current implementation does not explicitly check this parameter on the landing page, it provides a mechanism for future UI enhancements (e.g., displaying a "Payment was cancelled" message).

Sources: app/actions.ts L26-L27


After configuring the session parameters, the action creates the session and handles the response.

Session Creation Flow

The response handling at app/actions.ts L30-L32

checks for the presence of session.url before redirecting. The Stripe API response includes:

FieldTypeDescription
idstringUnique session identifier (e.g., cs_test_a1b2c3...)
urlstringStripe-hosted checkout page URL
amount_totalnumberTotal amount in cents (1000)
currencystringCurrency code (usd)
payment_statusstringInitial status (unpaid)

The redirect() function from Next.js triggers a 307 Temporary Redirect, sending the user to Stripe's hosted checkout page where they complete payment.

Sources: app/actions.ts L11-L32


The createCheckoutSession action is invoked from two locations on the landing page, both using the same form action pattern.

Landing Page Integration Points

Both forms follow the identical pattern:

  1. Import the server action: import { createCheckoutSession } from "./actions" at app/page.tsx L5
  2. Create a form with action={createCheckoutSession} attribute
  3. Include a submit button (wrapped in BeamButton component)

When the user clicks either button:

  • The browser triggers form submission
  • Next.js intercepts the submission and invokes the server action
  • The action executes server-side
  • The user is redirected to Stripe

This pattern eliminates the need for:

  • Manual fetch/POST requests
  • Client-side API key handling
  • State management for loading states
  • Error boundary setup (handled by Next.js)

Sources: app/page.tsx L5

app/page.tsx L62-L67

app/page.tsx L181-L185


The action imports the stripe client from @/lib/stripe, which must be configured with the secret API key.

Stripe Client Initialization (Expected Pattern)

While the lib/stripe.ts file is not included in the provided code, it must export a configured Stripe client. Based on .env.example at .env.example L11

the expected configuration is:

Environment VariablePurpose
STRIPE_SECRET_KEYServer-side API key for creating sessions
STRIPE_PUBLISHABLE_KEYClient-side key (not used in this action)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYPublic client-side key
STRIPE_WEBHOOK_SECRETFor webhook signature verification (see Stripe Webhook Handling)

The secret key must never be exposed to the client, which is why the checkout session creation happens in a server action rather than client-side code.

Sources: app/actions.ts L4

.env.example L9-L12


The current implementation at app/actions.ts L7-L33

does not include explicit error handling. If the Stripe API call fails, the error will propagate through Next.js's error boundary system.

Potential Error Scenarios

Error TypeCauseBehavior
Invalid API keySTRIPE_SECRET_KEY not set or incorrectStripe SDK throws error, Next.js shows error page
Network failureStripe API unreachableFetch timeout, error boundary activated
Invalid configurationMalformed session parametersStripe API returns 400 error
Missing origin headerEdge case in origin detectionUses localhost fallback

The absence of try-catch blocks means errors are handled by Next.js's default error handling, which displays the error page (app/error.tsx if it exists, or default Next.js error UI).

For production systems, consider adding:

  • Explicit error handling with user-friendly messages
  • Logging to track failed checkout attempts
  • Retry logic for transient network failures
  • Validation of environment variables at startup

Sources: app/actions.ts L7-L33


The server action pattern provides inherent security benefits:

Security FeatureImplementationBenefit
Server-side execution"use server" directiveAPI keys never exposed to client
HTTPS enforcementVercel production environmentProtects session data in transit
No CSRF vulnerabilityNext.js handles CSRF tokens automaticallyServer actions include built-in protection
Origin validationUses origin headerEnsures redirects stay within app domain

The redirect URLs constructed at app/actions.ts L26-L27

use the detected origin, ensuring users are redirected back to the legitimate application domain and not a spoofed site.

However, the cancel URL query parameter (canceled=true) is not currently validated or used, presenting a minor XSS consideration if future code displays this parameter without sanitization.

Sources: app/actions.ts L1

app/actions.ts L8-L9

app/actions.ts L26-L27


The session_id generated by Stripe serves as the primary correlation key linking payment to repository access. This ID flows through multiple systems:

session_id Propagation Flow

The session_id enables manual correlation between:

  1. Payment records in Stripe Dashboard
  2. GitHub connection events in Vercel logs
  3. Automation trigger notifications in ntfy.sh

This correlation is essential because the system has no database—all correlation happens through log inspection. See Data Flow & Correlation for the complete correlation strategy.

Sources: app/actions.ts L26


The checkout session creation depends on several environment variables and external configurations:

ConfigurationLocationPurpose
STRIPE_SECRET_KEY.env fileAuthenticates API requests
NEXT_PUBLIC_APP_URL.env fileCould be used for origin construction (not currently used)
Stripe DashboardExternalProduct catalog, webhook endpoint configuration
Vercel environment variablesDeployment platformProduction secret management

See Environment Variables for complete configuration documentation.

Sources: .env.example L8-L14

Refresh this wiki

Last indexed: 23 November 2025 (922b35)

On this page

Ask Devin about godeep.wiki-jb

04.a - Stripe-Checkout-Creation | DeepWiki | godeep.wiki